// Package controller 控制器的函数 包含gin的句柄
// 一些实验性的函数
package controller

import (
    "log"

    "github.com/gorilla/websocket"
    "github.com/gin-gonic/gin"
    "github.com/olahol/melody"
    "github.com/streadway/amqp"
)

// websocket句柄 TODO
func wsHandler(c *gin.Context) {
    var upgrader = websocket.Upgrader{
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
    }

    conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
    if err != nil {
        log.Println(err)
        return
    }
    defer conn.Close()
}

// rabbitmq 消息发布句柄
func mqpublisherHandler(m *melody.Melody, exchangename, exchangekind string, msg []byte, keys...string) error {
    conn, err := amqp.Dial("amqp://guest:guest@127.0.0.1:5672")
    if nil != err {
        log.Println(err)
        return err
    }
    defer conn.Close()

    ch, err := conn.Channel()
    if nil != err {
        log.Println(err)
        return err
    }
    defer ch.Close()

    err = ch.ExchangeDeclare(exchangename, exchangekind, true, false, false, false,  nil)
    if nil != err {
        log.Println(err)
        return err
    }

    for _, k := range keys {
        err = ch.Publish("logs_direct", k, false, false, amqp.Publishing{
            ContentType: "text/plain",
            Body: msg,
        })
        if nil != err {
            log.Println(err)
            return err
        }
    }
    
    log.Printf("[x] Send %s", msg)
    return nil
}

// rabbitmq 消息订阅句柄
func mqsubscriberHandler(m *melody.Melody, exchangename, exchangekind string, keys...string) {
    conn, err := amqp.Dial("amqp://guest:guest@127.0.0.1:5672")
    dealError(err, "fail to open rabbitmq")
    defer conn.Close()

    ch, err := conn.Channel()
    dealError(err, "fial to open channel")
    defer ch.Close()

    err = ch.ExchangeDeclare(exchangename, exchangekind, true, false, false, false,  nil)
    dealError(err, "fail to declare an exchange")

    q, err := ch.QueueDeclare("", false, false, true, false, nil)
    dealError(err, "fail to declare a queue")

    for _, s := range keys {
        log.Printf("Binding queue %s to exchange %s with routing key %s", q.Name, "logs_direct", s)
        err = ch.QueueBind(q.Name, s, "logs_direct", false, nil)
        dealError(err, "Failed to bind a queue")
    }

    msgs, err := ch.Consume(q.Name, "", true, false, false, false, nil)
    dealError(err, "Failed to register a consumer")

    forever := make(chan bool)
    go func() {
        for d := range msgs {
            log.Printf(" [x] %s", d.Body)
            m.Broadcast(d.Body)
        }
    }()

    log.Printf(" [*] Waiting for logs. To exit press CTRL+C")
    <-forever
}
